﻿using SyncFileCommon.BLL;
using SyncFileCommon.Class;
using System.IO.Pipes;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Text;

namespace SyncFileService
{
    internal class Program
    {
        /// <summary>
        /// 是否以Windows服务运行
        /// </summary>
        public static bool IsWindowsServiceRun = false;

        [DllImport("kernel32.dll")]
        private static extern IntPtr GetConsoleWindow();

        static void Main(string[] args)
        {

            try
            {
                //启动为Windows服务
                ServiceBase.Run(new WindowsServiceHelper());

                //如果没有使用Windows服务运行
                if (!IsWindowsServiceRun)
                {
                    var consoleWindowHandle = GetConsoleWindow();
                    //判断是否以控制台运行
                    if (consoleWindowHandle == IntPtr.Zero)
                    {
                        //以windows普通窗体运行
                        Run(args); 
                        while (true)
                        {
                            //保持程序不关闭
                            Thread.Sleep(1000);
                        }
                    }
                    else
                    {
                        //以控制台运行
                        Run(args);
                        Console.ReadLine();
                    }
                }
            }
            catch
            {

            } 
        }

        /// <summary>
        /// 管道通信服务端
        /// </summary>
        private static NamedPipeServerStream PipeServer;

        public static void Run(string[] args)
        {
            //增加排斥原子，防止配置端和服务程序同时启动服务
            bool createNew;
            System.Threading.Mutex mutex = new System.Threading.Mutex(true, "JLSyncFile", out createNew);
            if (createNew)
            {
                SyncFileCommon.BLL.ServerBLL _server = new SyncFileCommon.BLL.ServerBLL();
                _server.ServerStart();

                Task.Run(() =>
                {
                    while (true)
                    {
                        //启动客户端同步任务
                        SyncPlanBLL.RunSyncPlan();
                        Thread.Sleep(1000);
                    }
                });

                //创建命名管道服务端
                PipeServer = new NamedPipeServerStream("SyncFile", PipeDirection.In);

                Task.Run(() =>
                {
                    while (true)
                    {
                        try
                        {
                            if (!PipeServer.IsConnected)
                            {
                                PipeServer.WaitForConnection();
                            }

                            // 读取字节大小
                            byte[] _sizeBuffer = new byte[sizeof(int)];
                            PipeServer.Read(_sizeBuffer, 0, _sizeBuffer.Length);
                            int _messageSize = BitConverter.ToInt32(_sizeBuffer, 0);
                            // 消息内容
                            byte[] _responseBytes = new byte[_messageSize];
                            int _bytesRead = PipeServer.Read(_responseBytes, 0, _responseBytes.Length);
                            string _response = Encoding.UTF8.GetString(_responseBytes, 0, _bytesRead);

                            //如果管道收到消息为修改配置"ServerConfigUpdate"，则重新加载配置
                            if (_response == "ServerConfigUpdate")
                            {
                                _server.ServerReLoadConfig();
                            }

                            PipeServer.Disconnect();
                        }
                        catch (Exception ex)
                        {

                        }
                        Thread.Sleep(1000);
                    }
                });


            }
            else
            {
                Console.WriteLine(" 配置程序已运行，无法重复运行");
            }
        }
    }

    public partial class WindowsServiceHelper : System.ServiceProcess.ServiceBase
    { 

        public WindowsServiceHelper()
        {

        }

        protected override void OnStart(string[] args)
        {
            base.OnStart(args);
            Program.IsWindowsServiceRun = true;
            Program.Run(args);
        }

        protected override void OnStop()
        {
            base.OnStop();
        }
    }

}
